package com.godme.concurrent.pattern;

import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.atomic.AtomicInteger;

public class ProducerConsumerPattern {


    static class Pipe<T>  extends ArrayBlockingQueue<T> {

        public Pipe() {
            super(50);
        }
    }


    static class ProducerThread extends Thread {

        private final Pipe<Integer> pipe;
        private final AtomicInteger counter;

        public ProducerThread(String name, AtomicInteger counter, Pipe<Integer> pipe){
            super(name);
            this.pipe = pipe;
            this.counter = counter;
        }


        @Override
        public void run() {
            while(true){
                pipe.offer(counter.getAndIncrement());
                try{
                    sleep(500);
                }catch (Exception e){
                    e.printStackTrace();
                }
            }
        }
    }


    static class ConsumerThread extends Thread{
        private final Pipe<Integer> pipe;

        public ConsumerThread(String name, Pipe<Integer> pipe){
            super(name);
            this.pipe = pipe;
        }

        @Override
        public void run() {
            while(true){
                try {
                    System.err.println(getName() + "\t" + pipe.take());
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    public static void main(String[] args) {
        Pipe<Integer> pipe = new Pipe<>();
        AtomicInteger counter = new AtomicInteger();
        for (int i = 0; i < 2; i++) {
            new ProducerThread("producer-"+i, counter, pipe).start();
        }
        for (int i = 0; i < 5; i++) {
            new ConsumerThread("consumer-"+i, pipe).start();
        }
    }
}
